#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
 
#include <linux/input.h>
#include "sample_comm.h" 
// 定义长按键的TICK数, 以及连发间隔的TICK数, 单位是毫秒ms
//#define KEY_DEBOUNCE_PERIOD     20   // 延时消抖已经在kernel驱动做了，应用层不需要做了
#define KEY_LONG_PERIOD         1000
#define KEY_CONTINUE_PERIOD     200
 
#define TRUE    1
#define FALSE   0
 
typedef unsigned int Bool;
typedef void (*pf)(void);
 
typedef enum
{
    APP_KEY1 = 0,
    APP_KEY2,
    APP_KEY_MAX_NUM
} KEY_NUM_E;
 
typedef enum {
    APP_KEY_STATE_INIT = 0,
    APP_KEY_STATE_WOBBLE,
    APP_KEY_STATE_PRESS,
    APP_KEY_STATE_LONG,
    APP_KEY_STATE_CONTINUE,
    APP_KEY_STATE_RELEASE
} KEY_STATE_E;
 
void key1DownAction(void)
{
    global_step_record = 1;
    printf("%s\n", __FUNCTION__);
}
 
void key1LongAction(void)
{
    global_step_record = 0;
    printf("%s\n", __FUNCTION__);
}
 
void key1ContinueAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key1DownUpAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key1LongUpAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key2DownAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key2LongAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key2ContinueAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key2DownUpAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
void key2LongUpAction(void)
{
    printf("%s\n", __FUNCTION__);
}
 
 
typedef struct
{
    KEY_NUM_E eKeyId;
    unsigned int downTick;
    unsigned int upTick;
    KEY_STATE_E eKeyCurState;      //key cur state(fsm)
    Bool bStateChangedFlag;        //state changed flag
 
    pf keyDownAction;
    pf keyLongAction;
    pf keyContinueAction;
    pf keyDownUpAction;
    pf keyLongUpAction;
} KEY_HANDLE_T;
 
 
KEY_HANDLE_T keyList[APP_KEY_MAX_NUM] =
{
    {APP_KEY1, 0, 0, APP_KEY_STATE_INIT, FALSE, key1DownAction, key1LongAction, key1ContinueAction, key1DownUpAction, key1LongUpAction},
    {APP_KEY2, 0, 0, APP_KEY_STATE_INIT, FALSE, key2DownAction, key2LongAction, key2ContinueAction, key2DownUpAction, key2LongUpAction},
};
 
 
void keyScan(unsigned long cur_ms, int value, KEY_HANDLE_T *key)
{
    if(key == NULL)
    {
        printf("key == NULL, return\n");
        return;
    }
 
    switch(key->eKeyCurState)
    {
        case APP_KEY_STATE_INIT:
            if(value == 1)
            {
                key->downTick = cur_ms;
                key->keyDownAction(); //短按
            }
 
            if(value)
            {
                if((cur_ms - key->downTick) >= KEY_LONG_PERIOD)
                {
                    key->bStateChangedFlag = TRUE;
                    key->eKeyCurState = APP_KEY_STATE_LONG;
                }
            }
            else
            {
                key->upTick = cur_ms;
                key->bStateChangedFlag = TRUE;
                key->eKeyCurState = APP_KEY_STATE_INIT;
                key->keyDownUpAction(); //短按抬起
            }
            break;
 
        case APP_KEY_STATE_LONG:
            if(TRUE == key->bStateChangedFlag)
            {
                key->bStateChangedFlag = FALSE;
                key->keyLongAction(); //长按
            }
 
            if(value)
            {
                if((cur_ms - key->downTick) >= (KEY_LONG_PERIOD + KEY_CONTINUE_PERIOD))
                {
                    key->downTick = cur_ms;
                    key->bStateChangedFlag = TRUE;
                    key->eKeyCurState = APP_KEY_STATE_CONTINUE;
                }
            }
            else
            {
                key->upTick = cur_ms;
                key->bStateChangedFlag = TRUE;
                key->eKeyCurState = APP_KEY_STATE_INIT;
                key->keyLongUpAction(); //长按抬起
            }
            break;
 
        case APP_KEY_STATE_CONTINUE:
            if(TRUE == key->bStateChangedFlag)
            {
                key->bStateChangedFlag = FALSE;
                key->keyContinueAction(); //连发
            }
 
            if(value)
            {
                if((cur_ms - key->downTick) >= KEY_CONTINUE_PERIOD)
                {
                    key->downTick = cur_ms;
                    key->bStateChangedFlag = TRUE;
                    key->eKeyCurState = APP_KEY_STATE_CONTINUE;
                }
            }
            else
            {
                key->upTick = cur_ms;
                key->bStateChangedFlag = TRUE;
                key->eKeyCurState = APP_KEY_STATE_INIT;
                key->keyLongUpAction(); //长按抬起
            }
            break;
 
        default:
            break;
    }
}
 
/*
struct input_event {
    struct timeval time;
    __u16 type; //EV_SYN=0x00，EV_KEY=0x01
    __u16 code; //KEY_A，KEY_B，KEY_C
    __s32 value;//抬起=0，按下=1，长按=2
};
*/
 
int scan_key_main()
{
    int fd = 0;
    struct input_event buttons_event;
    KEY_HANDLE_T *curKey = NULL;
    unsigned long cur_ms = 0;
 
    //fd = open("/dev/event0", O_RDWR | O_NONBLOCK);
    fd = open("/dev/input/event0", O_RDWR);
    if (fd < 0)
    {
        printf("can't open!\n");
        return -1;
    }
 
    while (1)
    {
        read(fd, &buttons_event, sizeof(struct input_event));
 
        if(buttons_event.type == EV_SYN)
            continue;
 
        cur_ms = (buttons_event.time.tv_sec * 1000) + (buttons_event.time.tv_usec/1000);
 
        //打印时间，事件类型，事件码，事件值
        printf("cur_ms:%ld type:0x%x code:%d value:%d\n",
            cur_ms,
            buttons_event.type,
            buttons_event.code,
            buttons_event.value);
 
        // match key struct
        switch(buttons_event.code)
        {
            case KEY_A:
                curKey = &keyList[APP_KEY1];
                break;
            case KEY_B:
                curKey = &keyList[APP_KEY2];
                break;
            default:
                curKey = NULL;
                break;
        }
 
        keyScan(cur_ms, buttons_event.value, curKey);
    }
 
    return 0;
}
